package com.mapfinal.server.service.vectortile;

import java.util.List;

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Record;
import com.lambkit.db.mgr.MgrTable;
import com.lambkit.db.sql.condition.ConditionBuilder;
import com.mapfinal.server.MapfinalServer;
import com.mapfinal.server.cache.MapTable;
import com.mapfinal.server.cache.MapTableManager;
import com.mapfinal.server.service.tile.BoundingBox;

public class VectorTilePostgisServiceImpl implements VectorTileService {

	public byte[] vectorTile(VectorTileParam param) {
		if(param==null || StrKit.isBlank(param.getLayer())) {
			return null;
		}
		String tableName = getTableName(param.getLayer());
		MapTable mapTable = MapTableManager.me().build(tableName);
		if(mapTable==null || !mapTable.isValid()) {
			return null;
		}
		BoundingBox bbox = BoundingBox.tile2boundingBox(param);
		// System.out.println("bbox: " + bbox.getWest() + ", " + bbox.getSouth() + ", "
		// +bbox.getEast() + ", " + bbox.getNorth());
		
		StringBuilder strb = new StringBuilder();
		strb.append("SELECT ");
		strb.append("ST_AsMVT (tile, '");
		strb.append(tableName);// 图层名称
		strb.append("') tile");
		strb.append(" FROM ");
		strb.append("(");
		strb.append(" SELECT ");
		if("line".equals(param.getGeotype())) {
			strb.append(" st_asmvtgeom (ST_Boundary(st_transform(t.").append(mapTable.getGeoField()).append(", ").append(param.getCrs()).append(")),");
		} else if("convex".equals(param.getGeotype())) {
			strb.append(" st_asmvtgeom (ST_ConvexHull(st_transform(t.").append(mapTable.getGeoField()).append(", ").append(param.getCrs()).append(")),");
		} else {
			strb.append(" st_asmvtgeom (st_transform(t.").append(mapTable.getGeoField()).append(", ").append(param.getCrs()).append("),");
		}
		if (!"4326".equals(param.getCrs())) {
			strb.append("st_transform(st_makeenvelope (?,?,?,?, 4326),").append(param.getCrs()).append("),");
		} else {
			strb.append("st_makeenvelope (?,?,?,?, 4326),");// xmin,ymin,xmax,ymax
		}
		strb.append(" 4096,");
		strb.append(" 0,");
		strb.append(" TRUE");
		strb.append(" ) AS geom");
		strb.append(",").append(mapTable.select());
		strb.append(" FROM ");
		strb.append(tableName).append(" t ");
		// strb.append(" testgeo t");
		strb.append(" ) AS tile");
		strb.append(" WHERE");
		strb.append(" tile.geom IS NOT NULL ");
		
		MgrTable tbc = getTableView(tableName, true);
		if (tbc != null) {
			ConditionBuilder cb = getConditionsSQL(tbc).build("tile.");
			if(cb!=null && cb.hasSql()) {
				strb.append(cb.getSql());
			}
			List<Object> paras = cb.getParamList();
			int sz = paras.size() + 4;
			Object[] nps = new Object[sz];
			nps[0] = bbox.getWest();
			nps[1] = bbox.getSouth();
			nps[2] = bbox.getEast();
			nps[3] = bbox.getNorth();
			for (int i=4; i<sz; i++) {
				nps[i] = paras.get(i-4);
			}
			Record record = MapfinalServer.db().findFirst(strb.toString(), nps);
			return record!=null ? record.getBytes("tile") : null;
		} else {
			Record record = MapfinalServer.db().findFirst(strb.toString(), bbox.getWest(), bbox.getSouth(), bbox.getEast(),
					bbox.getNorth());
			return record!=null ? record.getBytes("tile") : null;
		}
	}
	
	private MgrTable getTableView(String tableName, boolean b) {
		// TODO Auto-generated method stub
		return null;
	}

	private String getTableName(String layer) {
		return layer;
	}

	private ConditionBuilder getConditionsSQL(MgrTable tbc) {
		// TODO Auto-generated method stub
		return null;
	}
}
